<?php
// +----------------------------------------------------------------------
// | ZengCMS [ 火火 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2018 http://zengcms.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 火火 <zengcms@qq.com>
// +----------------------------------------------------------------------

// +----------------------------------------------------------------------
// | Token服务类
// +----------------------------------------------------------------------
namespace app\api\service;

use app\api\lib\Auth;
use app\api\lib\exception\MissException;

class Token
{
    // jwt refresh_token有效期，单位秒
    private static $rtime = 30 * 24 * 60 * 60;
    /**
     * 生成token令牌
     * @param $data 用户数据(数组)
     * @return void
     */
    public static function generateToken($data)
    {
        return Auth::getInstance()->setDataFromArr($data)->encode()->getToken();
    }
    /**
     * 检查登录
     * @param $token 令牌
     * @return void
     */
    public static function needPermission($token)
    {
        // 从缓存中获取当前用户指定身份标识uid
        $uid = self::getCurrentTokenVar($token, 'uid');
        if ($uid) {
            return true;
        } else {
            throw new MissException([
                'message' => '请登录！',
                'httpCode' => 403
            ]);
        }
    }
    /**
     * 从缓存中获取当前用户指定身份标识
     * @param $token 令牌
     * @param $keys 字段,例:'uid'或['uid']
     * @return void
     */
    public static function getCurrentTokenVar($token, $keys)
    {
        $result = self::verifyToken($token);
        if ($result['isValid'] == false){
            throw new MissException([
                'message' => '请登录！',
                'httpCode' => 403
            ]);
        }
        $jwt = Auth::getInstance()->setToken($token)->decode();
        if(is_array($keys)){
            return $jwt->getDataArrByKey($keys);
        }
        return $jwt->getDataStringByKey($keys);
    }
    /**
     * 检查token是否存在，即是否有效
     * @param $token 令牌
     * @return void
     */
    public static function verifyToken($token)
    {
        if (!$token) {
            throw new MissException([
                'message' => 'token不允许为空！',
            ]);
        }
        $jwt = Auth::getInstance()->setToken($token)->decode();
        // 获取生成token时间
        $time = $jwt->getDataStringByKey('time');
        // 获取ip
        $ip = $jwt->getDataStringByKey('ip');
        // 获取uid
        $uid = $jwt->getDataStringByKey('uid');
        // 数据
        $data = $jwt->getDataArrByKey();
        $valid = false;
        $refresh_token = '';
        // 检查token前两部分即头部header和负荷playload
        if ($jwt->validate()) {
            if ($ip != get_reluser_ip()) {
                throw new MissException([
                    'message' => '登录异常！'
                ]);
            }
            // 检查token最后一部分即signature签名
            if ($jwt->verify()) {
                $valid = true;
            }
        } else {
            if (time() - $time <= self::$rtime) {
                $refresh_token = $token;
            }
        }
        return [
            // 判断是否登录
            'isValid' => $valid,
            // 通过refresh_token获取新的token
            'refresh_token' => $refresh_token,
            // 数据
            'data' => $data
        ];
    }
}
